from flask import Flask, request, jsonify
from flask.views import MethodView
from extension import db, BOOK_FIELDS
from models import Book
from dateutil.parser import parse

from flask_cors import CORS
# pip install python-dateutil
# 自动解析日期

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///books.sqlite"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

db.init_app(app)
# CORS(app, resources={r"/*": {"origins": "http://localhost:5173"}})

# 允许多个域
cors_origins = [
    "http://localhost:5173", 
    "http://localhost:3000", 
    # 你可以继续添加更多的域
]

CORS(app, resources={r"/*": {"origins": cors_origins}})

def formate_datetime(date_str):
    """将字符串格式的日期转换为 datetime 对象"""
    if date_str:
        return parse(date_str)

    return None


def format_book(book):
    """根据字段名称列表格式化书籍信息"""
    return {
        field: getattr(book, field)
        for field in BOOK_FIELDS if hasattr(book, field)
    }


def update_model_from_dict(model, data, fields=None):
    """根据传入的数据更新模型实例"""
    fields = fields or BOOK_FIELDS
    for field in fields:
        if field == 'publication_date' and field in data:
            setattr(model, field, formate_datetime(data[field]))
        elif field in data and hasattr(model, field):
            setattr(model, field, data[field])


class BookApi(MethodView):

    def get(self, book_id=None):
        """获取书籍信息"""
        results = []
        if book_id:
            with db.session() as session:
                book = session.get(book_id)
                if book:
                    results.append(format_book(book))
                else:
                    return {
                        'status': 'error',
                        'message': 'Book not found'
                    }, 404
        else:
            with db.session() as session:
                books = session.query(Book).all()
                results = [format_book(book) for book in books]

        res = {'status': 'success', 'message': '数据查询成功', 'results': results}
        return jsonify(res)

    def post(self):
        """添加新书籍"""
        form = request.json
        book = Book()
        update_model_from_dict(book, form)
        db.session.add(book)
        db.session.commit()
        return {'status': 'success', 'message': '数据添加成功'}, 201

    def put(self, book_id):
        """更新书籍信息"""
        book = Book.query.get(book_id)
        if not book:
            return {'status': 'error', 'message': 'Book not found'}, 404
        form = request.json
        update_model_from_dict(book, form)
        db.session.commit()
        return {'status': 'success', 'message': '数据修改成功'}

    def delete(self, book_id):
        """删除书籍"""
        book = Book.query.get(book_id)
        if book is None:
            return {'status': 'error', 'message': 'Book not found'}, 404
        db.session.delete(book)
        db.session.commit()
        return {'status': 'success', 'message': '数据删除成功'}


# 注册路由
book_view = BookApi.as_view('book_api')
app.add_url_rule('/books/', view_func=book_view, methods=['GET', 'POST'])
app.add_url_rule('/books/<int:book_id>',
                 view_func=book_view,
                 methods=['GET', 'PUT', 'DELETE'])

if __name__ == "__main__":
    with app.app_context():
        Book.init_db()
    app.run(debug=True)
